﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using WiimoteLib;
using Microsoft.Xna.Framework;

namespace SadlandVillage.Core
{
    public partial class Input
    {
        private static KeyboardState oldKeyboardState;
        private static KeyboardState keyboardState;

        private static WiimoteState oldWiimoteState;
        private static WiimoteState wiimoteState;

        public static Rectangle? WiimoteArea { get; private set; }
        private static Vector2? AspectRatio
        {
            get
            {
                Vector2? result = null;
                if (WiimoteArea != null)
                {
                    float x = (float)Constants.SCREEN_WIDTH / (float)WiimoteArea.Value.Width;
                    float y = (float)Constants.SCREEN_HEIGHT / (float)WiimoteArea.Value.Height;

                    result = new Vector2(x, y);
                }

                return result;
            }
        }

        private static Wiimote wiimote = new Wiimote();
        public static bool WiimoteConnected = false;

        public static void Begin()
        {
            keyboardState = Keyboard.GetState();
            wiimoteState = wiimote.WiimoteState;            
        }

        public static void End()
        {
            oldKeyboardState = keyboardState;
            oldWiimoteState = wiimoteState;
        }

        public static bool KeyPressed(Keys key)
        {
            return
                (oldKeyboardState.IsKeyDown(key)) &&
                (keyboardState.IsKeyUp(key));
        }

        public static bool KeyDown(Keys key)
        {
            return keyboardState.IsKeyDown(key);
        }       

        public static void Initialize()
        {
            try
            {
                wiimote = new Wiimote();
                wiimote.Connect();
                wiimote.SetReportType(Wiimote.InputReport.IRAccel, true);
                wiimote.SetLEDs(true, false, false, false);
                wiimoteState = wiimote.WiimoteState;
                WiimoteArea = null;
                WiimoteConnected = true;
            }
            catch (Exception)
            {
                WiimoteConnected = false;
            }
        }

        public static Crosshair GetCursor(Cursors cursor)
        {
            switch (cursor)
            {
                case Cursors.Cursor1:
                    return new Crosshair()
                    {
                        Position = new Vector2(ParseReceivedX(wiimoteState.IRState.RawX1), ParseReceivedY(wiimoteState.IRState.RawY1)),
                        Visible = wiimoteState.IRState.Found1,
                        Size = wiimoteState.IRState.Size1
                    };
                    
                case Cursors.Cursor2:
                    return new Crosshair()
                    {
                        Position = new Vector2(ParseReceivedX(wiimoteState.IRState.RawX2), ParseReceivedY(wiimoteState.IRState.RawY2)),
                        Visible = wiimoteState.IRState.Found2,
                        Size = wiimoteState.IRState.Size2
                    };
                case Cursors.Cursor3:
                    return new Crosshair()
                    {
                        Position = new Vector2(ParseReceivedX(wiimoteState.IRState.RawX3), ParseReceivedY(wiimoteState.IRState.RawY3)),
                        Visible = wiimoteState.IRState.Found3,
                        Size = wiimoteState.IRState.Size3
                    };
                case Cursors.Cursor4:
                    return new Crosshair()
                    {
                        Position = new Vector2(ParseReceivedX(wiimoteState.IRState.RawX4), ParseReceivedY(wiimoteState.IRState.RawY4)),
                        Visible = wiimoteState.IRState.Found4,
                        Size = wiimoteState.IRState.Size4
                    };
                default:
                    return new Crosshair();
            }
        }

        private static float ParseReceivedY(int rawY)
        {
            float transformed = Constants.SCREEN_HEIGHT - rawY;

            //Transforma a posição recebida de acordo com a calibragem do Wiimote
            if (WiimoteArea != null)
                transformed = transformed * AspectRatio.Value.Y;                

            return transformed;
        }

        private static float ParseReceivedX(int rawX)
        {
            float transformed = Constants.SCREEN_WIDTH - rawX;

            //Transforma a posição recebida de acordo com a calibragem do Wiimote
            if (WiimoteArea != null)
                transformed = transformed * AspectRatio.Value.X;

            return transformed;
        }

        public static bool ShouldDraw(Cursors cursor)
        {
            switch (cursor)
            {
                case Cursors.Cursor1:
                    return wiimoteState.IRState.Found1;
                case Cursors.Cursor2:
                    return wiimoteState.IRState.Found2;
                case Cursors.Cursor3:
                    return wiimoteState.IRState.Found3;
                case Cursors.Cursor4:
                    return wiimoteState.IRState.Found4;
                default:
                    return false;
            }
        }

        public static int Cursor1Size()
        {
            return wiimoteState.IRState.Size1;
        }

        public enum Cursors
        {
            Cursor1,
            Cursor2,
            Cursor3,
            Cursor4
        }

        public static void SetCalibration(Rectangle rectangle)
        {
            WiimoteArea = rectangle;
        }
    }

}

